#!/usr/bin/env node

/**
 * 前端质量检测脚本
 * 用于开发阶段快速检测代码质量
 */

import { execSync } from 'child_process'
import fs from 'fs'
import path from 'path'

const REPORT_FILE = 'docs/frontend-quality-report.md'

// 颜色输出
const colors = {
  reset: '\x1b[0m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  magenta: '\x1b[35m',
}

function log(message, color = 'reset') {
  // eslint-disable-next-line no-console
    console.log(`${colors[color]}${message}${colors.reset}`)
}

function runCommand(command, description) {
  log(`\n${'='.repeat(60)}`, 'blue')
  log(`📋 ${description}`, 'blue')
  log('='.repeat(60), 'blue')

  try {
    const output = execSync(command, {
      encoding: 'utf8',
      stdio: 'pipe',
      maxBuffer: 10 * 1024 * 1024
    })
    return { success: true, output }
  } catch (error) {
    return {
      success: false,
      output: error.stdout || error.message,
      error: error.stderr || error.message
    }
  }
}

// 检测结果收集器
const results = {
  syntax: [],
  type: [],
  dependency: [],
  build: [],
  test: [],
  a11y: [],
}

function addIssue(category, file, type, description, suggestion) {
  results[category].push({
    file,
    type,
    description,
    suggestion,
    severity: type.includes('error') ? '阻塞' : type.includes('warning') ? '高风险' : '一般',
  })
}

async function main() {
  const startTime = Date.now()

  log('\n🚀 开始前端质量检测...', 'magenta')
  log(`执行时间: ${new Date().toLocaleString()}`, 'magenta')

  // 1. 语法与格式检测
  log('\n1️⃣ 语法与格式检测', 'yellow')

  const lintResult = runCommand('npm run lint', 'ESLint 语法检测')
  if (!lintResult.success) {
    log('❌ ESLint 检测发现问题', 'red')
    const lines = lintResult.output.split('\n')
    lines.forEach(line => {
      if (line.includes('error') || line.includes('warning')) {
        addIssue('syntax', line.split(':')[0] || 'unknown', '语法错误', line, '请修复 ESLint 报告的问题')
      }
    })
  } else {
    log('✅ ESLint 检测通过', 'green')
  }

  const formatResult = runCommand('npm run format:check', 'Prettier 格式检测')
  if (!formatResult.success) {
    log('❌ 发现未格式化文件', 'red')
    addIssue('syntax', 'multiple', '格式错误', '存在未格式化的文件', '运行 npm run format 格式化代码')
  } else {
    log('✅ 代码格式检查通过', 'green')
  }

  // 2. 类型安全检测
  log('\n2️⃣ 类型安全检测', 'yellow')

  const typeResult = runCommand('npm run type-check', 'TypeScript 类型检测')
  if (!typeResult.success) {
    log('❌ TypeScript 类型检测发现错误', 'red')
    const lines = typeResult.error.split('\n')
    lines.forEach(line => {
      if (line.includes('error TS')) {
        addIssue('type', line.split('(')[0] || 'unknown', '类型错误', line, '修复 TypeScript 类型错误')
      }
    })
  } else {
    log('✅ TypeScript 类型检测通过', 'green')
  }

  // 3. 依赖关系与安全检查
  log('\n3️⃣ 依赖安全检查', 'yellow')

  const auditResult = runCommand('npm run audit', '依赖安全审计')
  if (!auditResult.success && auditResult.output.includes('vulnerabilities')) {
    log('⚠️  发现依赖安全漏洞', 'yellow')
    addIssue('dependency', 'package.json', '安全漏洞', auditResult.output, '运行 npm audit fix 修复漏洞')
  } else {
    log('✅ 依赖安全检查通过', 'green')
  }

  // 检查循环依赖
  const madgeResult = runCommand('npm run madge', '循环依赖检测')
  if (madgeResult.output.includes('Circular')) {
    log('⚠️  发现循环依赖', 'yellow')
    addIssue('dependency', 'src/', '循环依赖', madgeResult.output, '重构代码以消除循环依赖')
  } else {
    log('✅ 无循环依赖', 'green')
  }

  // 检查未使用的依赖
  const depcheckResult = runCommand('npm run depcheck', '未使用依赖检测')
  if (depcheckResult.output.includes('Unused')) {
    log('⚠️  发现未使用的依赖', 'yellow')
    addIssue('dependency', 'package.json', '未使用依赖', depcheckResult.output, '移除未使用的依赖包')
  } else {
    log('✅ 无未使用的依赖', 'green')
  }

  // 4. 关键路径冒烟测试
  log('\n4️⃣ 冒烟测试', 'yellow')

  const testResult = runCommand('npm run test:smoke', '运行冒烟测试')
  if (!testResult.success) {
    log('❌ 冒烟测试失败', 'red')
    addIssue('test', 'tests/', '测试失败', testResult.output, '修复失败的测试用例')
  } else {
    log('✅ 冒烟测试通过', 'green')
  }

  // 5. UI可访问性检查
  log('\n5️⃣ 可访问性检查', 'yellow')

  const a11yResult = runCommand('npm run test:a11y', '可访问性检测')
  if (!a11yResult.success) {
    log('⚠️  可访问性问题', 'yellow')
    addIssue('a11y', 'src/views/', '可访问性', a11yResult.output, '修复可访问性问题')
  } else {
    log('✅ 可访问性检查通过', 'green')
  }

  // 生成报告
  generateReport()

  const duration = ((Date.now() - startTime) / 1000).toFixed(2)
  log(`\n✨ 质量检测完成! 耗时: ${duration}s`, 'magenta')
  log(`📄 报告已生成: ${REPORT_FILE}`, 'magenta')

  // 返回退出码
  const hasBlockingIssues = Object.values(results).some(
    items => items.some(item => item.severity === '阻塞')
  )
  process.exit(hasBlockingIssues ? 1 : 0)
}

function generateReport() {
  const allIssues = Object.entries(results).flatMap(([category, issues]) =>
    issues.map(issue => ({ ...issue, category }))
  )

  // 按严重程度排序
  const severityOrder = { '阻塞': 0, '高风险': 1, '一般': 2 }
  allIssues.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity])

  let report = `# 前端质量检测报告

**生成时间**: ${new Date().toLocaleString()}
**项目**: n8n CRM Frontend
**检测范围**: 全项目

## 📊 检测概览

| 检测项 | 问题数 |
|--------|--------|
| 语法与格式 | ${results.syntax.length} |
| 类型安全 | ${results.type.length} |
| 依赖关系 | ${results.dependency.length} |
| 构建产物 | ${results.build.length} |
| 冒烟测试 | ${results.test.length} |
| 可访问性 | ${results.a11y.length} |
| **总计** | **${allIssues.length}** |

## 🔍 问题详情

`

  if (allIssues.length === 0) {
    report += '✅ **恭喜! 未发现任何问题。**\n'
  } else {
    report += `| 严重程度 | 类别 | 文件路径 | 问题类型 | 描述 | 修复建议 |
|----------|------|----------|----------|------|----------|
`
    allIssues.forEach(issue => {
      const severityIcon = {
        '阻塞': '🔴',
        '高风险': '🟡',
        '一般': '🟢',
      }[issue.severity]

      report += `| ${severityIcon} ${issue.severity} | ${issue.category} | \`${issue.file}\` | ${issue.type} | ${issue.description.substring(0, 50)}... | ${issue.suggestion} |\n`
    })
  }

  report += `\n## 📝 建议

`

  if (results.syntax.length > 0) {
    report += `### 语法与格式
- 运行 \`npm run format\` 自动格式化代码
- 运行 \`npm run lint -- --fix\` 自动修复部分 ESLint 错误

`
  }

  if (results.type.length > 0) {
    report += `### 类型安全
- 逐个修复 TypeScript 类型错误
- 避免使用 \`any\` 类型，使用具体类型或 \`unknown\`

`
  }

  if (results.dependency.length > 0) {
    report += `### 依赖管理
- 运行 \`npm audit fix\` 自动修复安全漏洞
- 移除 package.json 中未使用的依赖
- 重构代码消除循环依赖

`
  }

  report += `---
*本报告由质量检测脚本自动生成*
`

  // 确保 docs 目录存在
  const docsDir = path.dirname(REPORT_FILE)
  if (!fs.existsSync(docsDir)) {
    fs.mkdirSync(docsDir, { recursive: true })
  }

  fs.writeFileSync(REPORT_FILE, report)
}

main().catch(error => {
  log(`\n❌ 检测过程出错: ${error.message}`, 'red')
  process.exit(1)
})
